package com.liu.operate.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liu.operate.entity.base.OperateDetailInfo;
import com.liu.operate.entity.base.OperateInfo;
import com.liu.operate.entity.qo.OperateInfoDTO;
import com.liu.operate.mapper.OperateInfoMapper;
import com.liu.operate.service.IOperateDetailInfoService;
import com.liu.operate.service.IOperateInfoService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 操作信息表 服务实现类
 * </p>
 *
 * @author LiuChengLong
 * @since 2022-10-21
 */
@Service
public class OperateInfoServiceImpl extends ServiceImpl<OperateInfoMapper, OperateInfo> implements IOperateInfoService {

    @Resource
    private IOperateDetailInfoService operateDetailInfoService;

    @Override
    public void addOperate(OperateInfoDTO operateInfoDTO) {
        OperateInfo operateInfo = operateInfoDTO.getOperateInfo();
        operateInfo.setCreateBy(operateInfoDTO.getCreateBy());
        super.save(operateInfo);
        List<OperateDetailInfo> operateDetailInfoList = operateInfoDTO.getOperateDetailInfoList();
        operateDetailInfoList.forEach(o -> {
            o.setCreateBy(operateInfoDTO.getCreateBy());
            o.setOperateId(operateInfo.getId());
        });
        operateDetailInfoService.saveBatch(operateDetailInfoList);
    }

    @Override
    public void updateOperate(OperateInfoDTO operateInfoDTO) {
        OperateInfo operateInfo = operateInfoDTO.getOperateInfo();
        operateInfo.setCreateBy(operateInfoDTO.getCreateBy());
        super.updateById(operateInfo);
        List<OperateDetailInfo> operateDetailInfoList = operateInfoDTO.getOperateDetailInfoList();
        operateDetailInfoList.forEach(o -> {
            o.setCreateBy(operateInfoDTO.getCreateBy());
            o.setOperateId(operateInfo.getId());
        });
        operateDetailInfoService.updateBatchById(operateDetailInfoList);
    }

    @Override
    public List<OperateInfoDTO> getOperateInfoList() {
        List<OperateInfoDTO> result = new ArrayList<>();
        List<OperateInfo> operateInfoList = super.list();
        List<Integer> operateIdList = operateInfoList.stream().map(OperateInfo::getId).collect(Collectors.toList());
        QueryWrapper<OperateDetailInfo> operateDetailInfoQueryWrapper = new QueryWrapper<>();
        operateDetailInfoQueryWrapper.in("operate_id", operateIdList);
        List<OperateDetailInfo> operateDetailInfoList = operateDetailInfoService.list(operateDetailInfoQueryWrapper);
        Map<Integer, List<OperateDetailInfo>> operateDetailInfoListMap = operateDetailInfoList.stream().collect(Collectors.groupingBy(OperateDetailInfo::getOperateId));
        operateInfoList.forEach(o -> {
            OperateInfoDTO operateInfoDTO = new OperateInfoDTO();
            operateInfoDTO.setOperateInfo(o);
            List<OperateDetailInfo> operateDetailInfos = operateDetailInfoListMap.get(o.getId());
            operateInfoDTO.setOperateDetailInfoList(operateDetailInfos);
            result.add(operateInfoDTO);
        });
        return result;
    }

    @Override
    public List<OperateInfoDTO> getNpcOperateInfo() {
        QueryWrapper<OperateInfo> operateInfoQueryWrapper = new QueryWrapper<>();
        operateInfoQueryWrapper.eq("npc_operate", 1);
        List<OperateInfoDTO> result = new ArrayList<>();
        List<OperateInfo> operateInfoList = super.list(operateInfoQueryWrapper);
        List<Integer> operateIdList = operateInfoList.stream().map(OperateInfo::getId).collect(Collectors.toList());
        QueryWrapper<OperateDetailInfo> operateDetailInfoQueryWrapper = new QueryWrapper<>();
        operateDetailInfoQueryWrapper.in("operate_id", operateIdList);
        List<OperateDetailInfo> operateDetailInfoList = operateDetailInfoService.list(operateDetailInfoQueryWrapper);
        Map<Integer, List<OperateDetailInfo>> operateDetailInfoListMap = operateDetailInfoList.stream().collect(Collectors.groupingBy(OperateDetailInfo::getOperateId));
        operateInfoList.forEach(o -> {
            OperateInfoDTO operateInfoDTO = new OperateInfoDTO();
            operateInfoDTO.setOperateInfo(o);
            List<OperateDetailInfo> operateDetailInfos = operateDetailInfoListMap.get(o.getId());
            operateInfoDTO.setOperateDetailInfoList(operateDetailInfos);
            result.add(operateInfoDTO);
        });
        return result;
    }

    @Override
    public List<OperateInfo> getRandomOperate() {
        QueryWrapper<OperateInfo> wrapper = new QueryWrapper<>();
        wrapper.eq( "npc_operate", 0);
        List<OperateInfo> operateInfoList = baseMapper.selectList(wrapper);
        List<OperateInfo> result = null;
        // 事件列表长度不足2时，直接返回
        if (operateInfoList.size() >= 2){
            // 将list随机排序
            Collections.shuffle(operateInfoList);
            result = operateInfoList.subList(0, 2);
        }else {
            result = operateInfoList;
        }
        return result;
    }
}
